package com.ljd.sps;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

public class TakePhotoActivity extends Activity implements OnClickListener {
	private final static String TAG = "TakePhotoActivity";  
    private SurfaceView surfaceView;  
    private SurfaceHolder surfaceHolder;  
    private Camera camera;  
    private File picture;
    private int mType;
    private boolean mFrontCamera;
    
    private ProgressDialog mProgressDialog;
    
    // Photo call back   
    Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
        //@Override   
        public void onPictureTaken(byte[] data, Camera camera) {
        	new SavePictureTask().execute(data);
        	
        	mProgressDialog = new ProgressDialog(TakePhotoActivity.this);
        	mProgressDialog.setCancelable(false);
        	mProgressDialog.show();
        }  
    }; 
    

    // SurfaceHodler Callback handle to open the camera, off camera and photo size changes   
    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {  
  
        public void surfaceCreated(SurfaceHolder holder) {  
        	if (SmallphoneScannerActivity.LOG) {
        		Log.i(TAG, "surfaceCallback===="+mFrontCamera);
        	}

        	CameraInfo cameraInfo = new CameraInfo();  
        	int cameraCount = Camera.getNumberOfCameras(); // get cameras number
        	if (mFrontCamera) {
            	for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
            	    Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
            	    if ( cameraInfo.facing ==CameraInfo.CAMERA_FACING_FRONT) {
            	        try {
            	        	camera = Camera.open(camIdx);
            	        }catch (RuntimeException e) {  
            	            e.printStackTrace();  
            	        }
        	            break;
            	    }  
            	}
        	}else {
            	for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
            	    Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
            	    if ( cameraInfo.facing ==CameraInfo.CAMERA_FACING_BACK) {
            	        try {
            	            camera = Camera.open(camIdx);
            	        }catch (RuntimeException e) {  
            	            e.printStackTrace();  
            	        }
        	            break;
            	    }  
            	}
        	}

        	if (SmallphoneScannerActivity.LOG) {
        		Log.i(TAG, "camera is null:"+(camera == null));
        	}
        
        	if (camera == null) {
        		camera = Camera.open(); // Turn on the camera
        	}
        	
            try {  
                camera.setPreviewDisplay(holder); // Set Preview
            } catch (IOException e) {  
                camera.release();// release camera   
                camera = null;  
            }
        }  
  
        public void surfaceChanged(SurfaceHolder holder, int format, int width,  
                int height) {  
        	if (SmallphoneScannerActivity.LOG) {
        		Log.i(TAG,"====surfaceChanged");  
        	}
            Parameters parameters = getCameraParameters();
//          parameters.set("rotation", 180); // Arbitrary rotation   
            camera.setDisplayOrientation(90);
//          parameters.setPreviewSize(400, 300); // Set Photo Size   
            camera.setParameters(parameters); // Setting camera parameters   
            camera.startPreview(); // Start Preview
        }  
  
        public void surfaceDestroyed(SurfaceHolder holder) { 
        	if (SmallphoneScannerActivity.LOG) {
        		Log.i(TAG,"====surfaceDestroyed");  
        	}
            camera.stopPreview();// stop preview   
            camera.release(); // Release camera resources   
            camera = null;  
        }  
    };
    
    // save pic   
    class SavePictureTask extends AsyncTask<byte[], String, String> {
    	
        @Override  
        protected String doInBackground(byte[]... params) {
        	byte[] data = params[0];
//        	Bitmap src = BitmapFactory.decodeByteArray(data, 0, data.length);
        	Bitmap dest = ((CropCanvas)findViewById(R.id.crop_view)).getSubsetBitmap(data);

        	picture = new File(getFilesDir() + "/src.jpg");  
            
            try {  
                FileOutputStream fos = new FileOutputStream(picture.getPath()); // Get file output stream   
                if (dest.compress(Bitmap.CompressFormat.JPEG, 70, fos)) {
                	fos.flush();
                	fos.close();
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }
            if (SmallphoneScannerActivity.LOG) {
            	Log.i(TAG, "src data size:"+data.length);
            	Log.i(TAG, "dest bitmap:["+dest.getWidth()+"]["+dest.getHeight()+"]");
            	Log.i(TAG, "dest file size:"+picture.length());
            }
            dest.recycle();
            dest = null;
            
            System.gc();
            return null;
        }

		@Override
		protected void onPostExecute(String result) {
			// TODO Auto-generated method stub
			if (mProgressDialog != null) {
				mProgressDialog.dismiss();
				mProgressDialog = null;
			}
        	
			AdjustActivity.FRONT_CAMERA = mFrontCamera;
            Intent intent = new Intent(TakePhotoActivity.this, AdjustActivity.class);
			intent.putExtra(SmallphoneScannerActivity.EXTRA_PHOTO_TYPE, mType);
			startActivity(intent);
            finish();
		}
    }
    
    private class FocusCallBack implements Camera.AutoFocusCallback {
    	private int focusTime;
    	
    	public void onAutoFocus(boolean success, Camera camera) {
			// TODO Auto-generated method stub
			if (!success && focusTime < 2) {
				focusTime++;
				camera.autoFocus(this);
//				Toast.makeText(TakePhotoActivity.this, "对焦失败", Toast.LENGTH_SHORT).show();
				return;
			}

			camera.takePicture(null, null, pictureCallback); // picture
		}
    	
    }
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
        setContentView(R.layout.takephoto);  
        setupViews(getIntent());  
    }  
      
    private void setupViews(Intent intent){
    	mType = intent.getIntExtra(SmallphoneScannerActivity.EXTRA_PHOTO_TYPE, 0);
    	((CropCanvas)findViewById(R.id.crop_view)).setType(mType);
//    	switch(mType){
//    	case SmallphoneScannerActivity._4X6:
//    		findViewById(R.id.crop).setBackgroundResource(R.drawable.crop_4x6);
//    		break;
//    	case SmallphoneScannerActivity._3X5:
//    		findViewById(R.id.crop).setBackgroundResource(R.drawable.crop_3x5);
//    		break;
//    	case SmallphoneScannerActivity._SLIDER:
//    	case SmallphoneScannerActivity._NEGATIVES:
//    		findViewById(R.id.crop).setBackgroundResource(R.drawable.crop_slider_or_negative);
//    		break;
//    	}
    	
        surfaceView = (SurfaceView) findViewById(R.id.camera_preview); // Camera interface to instantiate components   
        surfaceHolder = surfaceView.getHolder(); // Camera interface to instantiate components   
        surfaceHolder.addCallback(surfaceCallback); // Add a callback for the SurfaceHolder   
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
          
        findViewById(R.id.take_photo).setOnClickListener(this);
        findViewById(R.id.flash_light).setOnClickListener(this);
        findViewById(R.id.flash_on).setOnClickListener(this);
        findViewById(R.id.flash_off).setOnClickListener(this);
        findViewById(R.id.camera).setOnClickListener(this);
        findViewById(R.id.cancel).setOnClickListener(this);
    }  
      
    private void switchCamera() {
    	CameraInfo cameraInfo = new CameraInfo();  
    	int cameraCount = Camera.getNumberOfCameras(); // get cameras number
    	if (mFrontCamera) {
        	for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
        	    Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
        	    if ( cameraInfo.facing ==CameraInfo.CAMERA_FACING_BACK) {
        	        try {
        	        	camera.stopPreview();// stop preview   
        	        	camera.release(); // Release camera resources   
        	        	camera = null;
        	        	
        	            camera = Camera.open(camIdx);
    	                camera.setPreviewDisplay(surfaceHolder); // Set Preview
    	                

    	                Parameters parameters = getCameraParameters();
//    	              parameters.set("rotation", 180); // Arbitrary rotation   
    	                camera.setDisplayOrientation(90);
//    	              parameters.setPreviewSize(400, 300); // Set Photo Size   
    	                camera.setParameters(parameters); // Setting camera parameters   
    	                camera.startPreview(); // Start Preview
    	                
    	                mFrontCamera = false;
        	        }catch (IOException e) {  
    	                camera.release();// release camera   
    	                camera = null;  
    	            } catch (RuntimeException e) {  
        	            e.printStackTrace();  
        	        }
    	            break;
        	    }  
        	}
    	}else {
        	for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
        	    Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
        	    if ( cameraInfo.facing ==CameraInfo.CAMERA_FACING_FRONT) {
        	        try {
        	        	camera.stopPreview();// stop preview   
        	        	camera.release(); // Release camera resources   
        	        	camera = null;
        	        	
        	            camera = Camera.open(camIdx);
    	                camera.setPreviewDisplay(surfaceHolder); // Set Preview

    	                Parameters parameters = getCameraParameters();
//    	              parameters.set("rotation", 180); // Arbitrary rotation   
    	                camera.setDisplayOrientation(90);
//    	              parameters.setPreviewSize(400, 300); // Set Photo Size   
    	                camera.setParameters(parameters); // Setting camera parameters  
    	                camera.startPreview(); // Start Preview
    	                
    	                mFrontCamera = true;
        	        }catch (IOException e) {  
    	                camera.release();// release camera   
    	                camera = null;  
    	            } catch (RuntimeException e) {  
        	            e.printStackTrace();  
        	        }
    	            break;
        	    }  
        	}
    	}
    }
    
    private void switchFlah(boolean on) {
    	if (on) {
    		Parameters para = camera.getParameters();
    		para.setFlashMode(Parameters.FLASH_MODE_AUTO);
    		camera.setParameters(para);
    	}else {
    		Parameters para = camera.getParameters();
    		para.setFlashMode(Parameters.FLASH_MODE_OFF);
    		camera.setParameters(para);
    	}
    }
    
    @Override  
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_CAMERA  
                || keyCode == KeyEvent.KEYCODE_SEARCH) {
            takePic();  
            return true;  
        }  
        return super.onKeyDown(keyCode, event);  
    }
  
    private void takePic() {
    	camera.autoFocus(new FocusCallBack());
    }   

	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.take_photo:
			takePic();
			break;
		case R.id.flash_light:
			View flashPanel = findViewById(R.id.flash_panel);
			if (flashPanel.getVisibility() == View.VISIBLE) {
				Animation myAnimation= AnimationUtils.loadAnimation(this,R.anim.anim_out);
				flashPanel.setVisibility(View.GONE);
				flashPanel.setAnimation(myAnimation);
			}else {
				Animation myAnimation= AnimationUtils.loadAnimation(this,R.anim.anim_in);
				flashPanel.setVisibility(View.VISIBLE);
				flashPanel.setAnimation(myAnimation);
			}
			break;
		case R.id.flash_on:
			switchFlah(true);
			
			flashPanel = findViewById(R.id.flash_panel);
			Animation myAnimation= AnimationUtils.loadAnimation(this,R.anim.anim_out);
			flashPanel.setVisibility(View.GONE);
			flashPanel.setAnimation(myAnimation);
	        findViewById(R.id.flash_light).setBackgroundResource(R.drawable.flash_auto);
			break;
		case R.id.flash_off:
			switchFlah(false);
			
			flashPanel = findViewById(R.id.flash_panel);
			myAnimation= AnimationUtils.loadAnimation(this,R.anim.anim_out);
			flashPanel.setVisibility(View.GONE);
			flashPanel.setAnimation(myAnimation);
	        findViewById(R.id.flash_light).setBackgroundResource(R.drawable.flash_off);
			break;
		case R.id.camera:
			switchCamera();
			break;
		case R.id.cancel:
			finish();
			break;
		}
	}
	
	private Parameters getCameraParameters() {
		Parameters parameters = camera.getParameters(); // Camera parameters to obtain   
        parameters.setPictureFormat(PixelFormat.JPEG);// Setting Picture Format   
        switch(mType){
    	case SmallphoneScannerActivity._NEGATIVES:
            parameters.setFocusMode(Parameters.FOCUS_MODE_MACRO);  
    		break;
		default:
            parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);  
    		break;
    	}
        List<Size> sizeList = parameters.getSupportedPictureSizes();
        Size pSize = sizeList.get(0);
        for (int i = 0; i < sizeList.size(); i++) {
    		Size s = sizeList.get(i);
    		if (SmallphoneScannerActivity.LOG) {
    			Log.d(TAG, "support size:["+s.width+"]["+s.height+"]");
    		}
    		if (pSize.width < s.width) {
    			pSize = s;
    		}
    	}
        parameters.setPictureSize(pSize.width, pSize.height);

//        List<Size> previewSizeList = parameters.getSupportedPreviewSizes();
//        if (SmallphoneScannerActivity.LOG) {
//        	for (int i = 0; i < previewSizeList.size(); i++) {
//        		Size s = previewSizeList.get(i);
//        		Log.d(TAG, "support preview size:["+s.width+"]["+s.height+"]");
//        	}
//        }
//        parameters.setPictureSize(previewSizeList.get(0).width, previewSizeList.get(0).height);
        return parameters;
	}
}
